package Bluetooth_NXT;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.*;
import javax.bluetooth.RemoteDevice;
import lejos.nxt.*;
import lejos.nxt.comm.*;


public class BTCommunication_Client 
{
	private boolean _isConnected;
	private NXTConnection _connection = null;
	private RemoteDevice _remoteDevice;
	private String _serverName = null;
	private final byte[] _pin = new byte[]{(byte)'1', (byte)'2', (byte)'3', (byte)'4'};
	private byte _visible = 1;
	private byte _invisible = 0;
	private Vector _storedDeviceList;
	private Vector _newDeviceList;
	private DataOutputStream _dataOut;
	private DataInputStream _dataIn;
	
	public BTCommunication_Client( String ServerName )
	{
		_isConnected = false;
		_serverName = ServerName.toUpperCase(); //convert the string to upper case
		byte[] bca = new byte[]{0,0,0,0};
		if (!Bluetooth.getPower())
			Bluetooth.setPower(true);
		while(!Bluetooth.getPower()) {} //Wait until power is on
		if(Bluetooth.getVisibility() < 1) // 1 if visible, 0 if invisible
			Bluetooth.setVisibility(_visible); //Set visible
		_storedDeviceList = Bluetooth.getKnownDevicesList(); //get bluetooth  devices
		_newDeviceList = Bluetooth.inquire(10, 5, bca);//Any Device
		if (_storedDeviceList != null)//if the Device in known
		{
			for (int i = 0; i < _storedDeviceList.size(); i++)
			{				
				RemoteDevice rd = ((RemoteDevice)_storedDeviceList.elementAt(i));
				if(rd.getFriendlyName(false).equals(_serverName))
					_remoteDevice = rd;			
			}
		}			
		if (_remoteDevice == null && _newDeviceList != null)//search for the Device if its not known
		{
			for (int i = 0; i < _newDeviceList.size(); i++)
			{				
				RemoteDevice rd = ((RemoteDevice)_newDeviceList.elementAt(i));
				if(rd.getFriendlyName(false).equals(_serverName))
					_remoteDevice = rd;
			}			
			if(_remoteDevice != null)
				Bluetooth.addDevice(_remoteDevice);//add remote Device				
		}
		if (_remoteDevice == null)
		{
			//Start Debug
			LCD.drawString("Error no RD\n, _remoteDevice", 1, 1);
			try{
				Thread.sleep(3000);
				}
				catch (InterruptedException e){}
				LCD.clear();
				//End Debug
		}
		//Start Debug
		LCD.drawString("Found\n" + _remoteDevice.getFriendlyName(false), 0, 1);
		try{
			Thread.sleep(3000);
			}
			catch (InterruptedException e){}
			LCD.clear();
			//End Debug
		
	}
//	public NXTConnection GetNXTConnection()
//	{
//		_connection.setIOMode(NXTConnection.RAW);//NXTConnection.PACKET
//		return _connection;
//	}
	public void ConnectServer()
	{
		//Start Debug
		LCD.drawString("connect...", 0, 1);
		try{
			Thread.sleep(10000);
			}
			catch (InterruptedException e){
				
			}
			LCD.clear();
			//End Debug
		try
		{
			if (_remoteDevice != null && _remoteDevice.getFriendlyName(false).equals(_serverName)); //only the right device should connect
			{
				_connection = Bluetooth.connect(_remoteDevice);
				if (_connection == null)
					_connection = Bluetooth.connect(_remoteDevice.getDeviceAddr(), NXTConnection.RAW, _pin);//if pin is required
				byte[] connectionStatus = Bluetooth.getConnectionStatus();
				if (_connection == null || connectionStatus == null)//check for return codes
				{
					//Start Debug
					LCD.drawString("Not\nconnected", 0, 1);
					try{
						Thread.sleep(10000);
						}
						catch (InterruptedException e){}
						LCD.clear();
						//End Debug
				}
				else
				{
					_isConnected = true;
					_connection.setIOMode(NXTConnection.RAW);//NXTConnection.PACKET
//					OpenDataStream();
					//Start Debug
					LCD.drawString("Connected to MAC\n" + _connection.getAddress(), 0, 1);
					LCD.drawString("Name\n" + _remoteDevice.getFriendlyName(true), 0, 3);
					try{
						Thread.sleep(3000);
						}
						catch (InterruptedException e){}
						LCD.clear();
						//End Debug
				}
			}
		}
		catch (Exception e){
			LCD.drawString("Error in\nConnectServer!", 0, 0);
		}
	}
	public boolean IsConnected()
	{
		return _isConnected;
	}
	public void OpenDataStream()
	{
		if(_connection != null)
		{
			try
			{
				_connection.setIOMode(NXTConnection.RAW);//NXTConnection.PACKET
				_dataOut = _connection.openDataOutputStream();
				_dataIn = _connection.openDataInputStream();
//				byte[] b = {-128,-127,-1,0,1,10,120,127};/* work 2 */
				byte[] b2 = new byte[256];
				int offset = 128;
				for (int i=0;i<b2.length;i++)
				{
					b2[i]=(byte)(i-offset);
				}
//				int i2 = 5; /* work 1 */
//				_dataOut.writeInt(i2);/* work 1 */
//				_dataOut.write(b);/* work 2 */
				_dataOut.write(b2);
				_dataOut.flush();
				LCD.drawString("Write\ni2", 0, 0);
			}catch (Exception e){
				LCD.drawString("Error in\nOpenDataStream!", 0, 0);
			}
		}
	}
	public void DisconnectServer()
	{
		if(_connection != null)
		{
				try
				{
					_dataOut.close();
					_dataIn.close();
					_connection.close();
				}catch(Exception e){
					LCD.drawString("Error in\nDisconnectServer!", 0, 0);
				}
		}
		if(Bluetooth.getVisibility() > 0) // 1 if visible, 0 if invisible
			Bluetooth.setVisibility(_invisible); //Set invisible
		if (Bluetooth.getPower())
			Bluetooth.setPower(false);
	}
}
